package com.smart.community.region.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.commons.utils.StringUtils;
import com.smart.community.region.entity.Building;
import com.smart.community.region.entity.Household;
import com.smart.community.region.entity.Unit;
import com.smart.community.region.mapper.BuildingMapper;
import com.smart.community.region.mapper.HouseholdMapper;
import com.smart.community.region.mapper.UnitMapper;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 社区数据导入服务
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Slf4j
@Service
public class CommunityDataImportService {

    @Autowired
    private BuildingMapper buildingMapper;
    
    @Autowired
    private UnitMapper unitMapper;
    
    @Autowired
    private HouseholdMapper householdMapper;

    /**
     * 批量导入楼栋数据
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"building:page", "building:detail", "building:byNo"}, allEntries = true)
    public int importBuildings(List<Map<String, Object>> buildingData, Long communityId) {
        long startTime = System.currentTimeMillis();
        log.info("开始导入楼栋数据，社区ID：{}，数据量：{}", communityId, buildingData != null ? buildingData.size() : 0);
        
        try {
            // 参数验证
            if (buildingData == null || buildingData.isEmpty()) {
                log.warn("楼栋数据为空，返回0");
                return 0;
            }
            if (communityId == null) {
                log.warn("社区ID为空，返回0");
                return 0;
            }
            
            List<Building> buildings = new ArrayList<>();
            for (Map<String, Object> data : buildingData) {
                try {
                    Building building = convertToBuilding(data, communityId);
                    buildings.add(building);
                } catch (Exception e) {
                    log.error("转换楼栋数据失败：{}，错误：{}", data, e.getMessage(), e);
                    // 继续处理其他数据，不中断整个导入过程
                }
            }
            
            int successCount = 0;
            int errorCount = 0;
            for (Building building : buildings) {
                try {
                    buildingMapper.insert(building);
                    successCount++;
                    log.debug("楼栋导入成功：{}", building.getBuildingNo());
                } catch (Exception e) {
                    errorCount++;
                    log.error("楼栋导入失败：{}，错误：{}", building.getBuildingNo(), e.getMessage(), e);
                    // 生产环境优雅降级，记录错误但继续处理
                }
            }
            
            long endTime = System.currentTimeMillis();
            log.info("楼栋数据导入完成，成功：{}，失败：{}，总数：{}，耗时：{}ms", successCount, errorCount, buildingData.size(), endTime - startTime);
            return successCount;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("楼栋数据导入异常，社区ID：{}，耗时：{}ms", communityId, endTime - startTime, e);
            return 0; // 生产环境优雅降级
        }
    }

    /**
     * 批量导入单元数据
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"unit:page", "unit:detail", "unit:byNo"}, allEntries = true)
    public int importUnits(List<Map<String, Object>> unitData, Long communityId, Map<String, Long> buildingIdMap) {
        long startTime = System.currentTimeMillis();
        log.info("开始导入单元数据，社区ID：{}，数据量：{}", communityId, unitData != null ? unitData.size() : 0);
        
        try {
            // 参数验证
            if (unitData == null || unitData.isEmpty()) {
                log.warn("单元数据为空，返回0");
                return 0;
            }
            if (communityId == null) {
                log.warn("社区ID为空，返回0");
                return 0;
            }
            if (buildingIdMap == null) {
                log.warn("楼栋ID映射为空，返回0");
                return 0;
            }
            
            List<Unit> units = new ArrayList<>();
            for (Map<String, Object> data : unitData) {
                try {
                    Unit unit = convertToUnit(data, communityId, buildingIdMap);
                    units.add(unit);
                } catch (Exception e) {
                    log.error("转换单元数据失败：{}，错误：{}", data, e.getMessage(), e);
                    // 继续处理其他数据，不中断整个导入过程
                }
            }
            
            int successCount = 0;
            int errorCount = 0;
            for (Unit unit : units) {
                try {
                    unitMapper.insert(unit);
                    successCount++;
                    log.debug("单元导入成功：{}", unit.getUnitName());
                } catch (Exception e) {
                    errorCount++;
                    log.error("单元导入失败：{}，错误：{}", unit.getUnitName(), e.getMessage(), e);
                    // 生产环境优雅降级，记录错误但继续处理
                }
            }
            
            long endTime = System.currentTimeMillis();
            log.info("单元数据导入完成，成功：{}，失败：{}，总数：{}，耗时：{}ms", successCount, errorCount, unitData.size(), endTime - startTime);
            return successCount;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("单元数据导入异常，社区ID：{}，耗时：{}ms", communityId, endTime - startTime, e);
            return 0; // 生产环境优雅降级
        }
    }

    /**
     * 批量导入房户数据
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"household:page", "household:detail", "household:byCode"}, allEntries = true)
    public int importHouseholds(List<Map<String, Object>> householdData, Long communityId, 
                               Map<String, Long> buildingIdMap, Map<String, Long> unitIdMap) {
        long startTime = System.currentTimeMillis();
        log.info("开始导入房户数据，社区ID：{}，数据量：{}", communityId, householdData != null ? householdData.size() : 0);
        
        try {
            // 参数验证
            if (householdData == null || householdData.isEmpty()) {
                log.warn("房户数据为空，返回0");
                return 0;
            }
            if (communityId == null) {
                log.warn("社区ID为空，返回0");
                return 0;
            }
            if (buildingIdMap == null || unitIdMap == null) {
                log.warn("楼栋或单元ID映射为空，返回0");
                return 0;
            }
            
            List<Household> households = new ArrayList<>();
            for (Map<String, Object> data : householdData) {
                try {
                    Household household = convertToHousehold(data, communityId, buildingIdMap, unitIdMap);
                    households.add(household);
                } catch (Exception e) {
                    log.error("转换房户数据失败：{}，错误：{}", data, e.getMessage(), e);
                    // 继续处理其他数据，不中断整个导入过程
                }
            }
            
            int successCount = 0;
            int errorCount = 0;
            for (Household household : households) {
                try {
                    householdMapper.insert(household);
                    successCount++;
                    log.debug("房户导入成功：{}", household.getHouseholdCode());
                } catch (Exception e) {
                    errorCount++;
                    log.error("房户导入失败：{}，错误：{}", household.getHouseholdCode(), e.getMessage(), e);
                    // 生产环境优雅降级，记录错误但继续处理
                }
            }
            
            long endTime = System.currentTimeMillis();
            log.info("房户数据导入完成，成功：{}，失败：{}，总数：{}，耗时：{}ms", successCount, errorCount, householdData.size(), endTime - startTime);
            return successCount;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("房户数据导入异常，社区ID：{}，耗时：{}ms", communityId, endTime - startTime, e);
            return 0; // 生产环境优雅降级
        }
    }

    /**
     * 转换楼栋数据
     */
    private Building convertToBuilding(Map<String, Object> data, Long communityId) {
        if (data == null) {
            throw new IllegalArgumentException("楼栋数据不能为空");
        }
        
        Building building = new Building();
        
        building.setBuildingNo(getStringValue(data, "buildingNo"));
        building.setBuildingName(getStringValue(data, "buildingName"));
        building.setCommunityId(communityId);
        building.setBuildingType(getStringValue(data, "buildingType"));
        building.setFloorCount(getIntegerValue(data, "floorCount"));
        building.setUnitCount(getIntegerValue(data, "unitCount"));
        building.setHouseholdCount(0); // 初始为0
        building.setUnitsPerFloor(getIntegerValue(data, "unitsPerFloor"));
        building.setBuildYear(getIntegerValue(data, "buildYear"));
        building.setRemark(getStringValue(data, "remark"));
        
        // 设置默认值
        building.setStatus(1); // 启用状态
        building.setCreateBy(SecurityUtils.getCurrentUserId());
        building.setCreateTime(LocalDateTime.now());
        building.setUpdateBy(SecurityUtils.getCurrentUserId());
        building.setUpdateTime(LocalDateTime.now());
        
        return building;
    }

    /**
     * 转换单元数据
     */
    private Unit convertToUnit(Map<String, Object> data, Long communityId, Map<String, Long> buildingIdMap) {
        if (data == null) {
            throw new IllegalArgumentException("单元数据不能为空");
        }
        if (buildingIdMap == null) {
            throw new IllegalArgumentException("楼栋ID映射不能为空");
        }
        
        Unit unit = new Unit();
        
        String buildingNo = getStringValue(data, "buildingNo");
        Long buildingId = buildingIdMap.get(buildingNo);
        if (buildingId == null) {
            log.warn("楼栋不存在：{}，跳过该单元数据", buildingNo);
            throw new IllegalArgumentException("楼栋不存在：" + buildingNo);
        }
        
        unit.setUnitName(getStringValue(data, "unitName"));
        unit.setUnitNo(getStringValue(data, "unitNo"));
        unit.setCommunityId(communityId);
        unit.setBuildingId(buildingId);
        unit.setFloorCount(getIntegerValue(data, "floorCount"));
        unit.setRoomCount(getIntegerValue(data, "roomCount"));
        unit.setHouseholdCount(getIntegerValue(data, "householdCount"));
        unit.setHasElevator("是".equals(getStringValue(data, "hasElevator")) ? 1 : 0);
        unit.setElevatorCount(getIntegerValue(data, "elevatorCount"));
        unit.setDoorAccessType(getDoorAccessType(getStringValue(data, "doorAccessType")));
        unit.setRemark(getStringValue(data, "remark"));
        
        // 设置默认值
        unit.setStatus(1); // 正常使用
        unit.setCreateBy(SecurityUtils.getCurrentUserId());
        unit.setCreateTime(LocalDateTime.now());
        unit.setUpdateBy(SecurityUtils.getCurrentUserId());
        unit.setUpdateTime(LocalDateTime.now());
        
        return unit;
    }

    /**
     * 转换房户数据
     */
    private Household convertToHousehold(Map<String, Object> data, Long communityId, 
                                        Map<String, Long> buildingIdMap, Map<String, Long> unitIdMap) {
        if (data == null) {
            throw new IllegalArgumentException("房户数据不能为空");
        }
        if (buildingIdMap == null || unitIdMap == null) {
            throw new IllegalArgumentException("楼栋或单元ID映射不能为空");
        }
        
        Household household = new Household();
        
        String buildingNo = getStringValue(data, "buildingNo");
        Integer unitNo = getIntegerValue(data, "unitNo");
        Long buildingId = buildingIdMap.get(buildingNo);
        Long unitId = unitIdMap.get(buildingNo + "-" + unitNo);
        
        if (buildingId == null) {
            log.warn("楼栋不存在：{}，跳过该房户数据", buildingNo);
            throw new IllegalArgumentException("楼栋不存在：" + buildingNo);
        }
        if (unitId == null) {
            log.warn("单元不存在：楼栋{}单元{}，跳过该房户数据", buildingNo, unitNo);
            throw new IllegalArgumentException("单元不存在：楼栋" + buildingNo + "单元" + unitNo);
        }
        
        household.setHouseholdCode(getStringValue(data, "householdCode"));
        household.setCommunityId(communityId);
        household.setBuildingId(buildingId);
        household.setUnitId(unitId);
        household.setRoomNumber(getStringValue(data, "roomNumber"));
        household.setFloorNumber(getIntegerValue(data, "floorNumber"));
        household.setArea(getBigDecimalValue(data, "area"));
        household.setRoomType(getRoomType(getStringValue(data, "houseType")));
        household.setOrientation(getStringValue(data, "orientation"));
        household.setStatus(getHouseholdStatus(getStringValue(data, "status")));
        household.setDescription(getStringValue(data, "remark"));
        
        // 设置默认值
        household.setCreateBy(SecurityUtils.getCurrentUserId());
        household.setCreateTime(LocalDateTime.now());
        household.setUpdateBy(SecurityUtils.getCurrentUserId());
        household.setUpdateTime(LocalDateTime.now());
        
        return household;
    }

    /**
     * 获取门禁类型
     */
    private Integer getDoorAccessType(String type) {
        if (type == null) return 1; // 默认密码
        switch (type) {
            case "密码": return 1;
            case "刷卡": return 2;
            case "人脸识别": return 3;
            case "指纹": return 4;
            default: return 1;
        }
    }

    /**
     * 获取房间类型
     */
    private Integer getRoomType(String type) {
        if (type == null) return 2; // 默认两室
        switch (type) {
            case "一室": return 1;
            case "两室": return 2;
            case "三室": return 3;
            case "四室及以上": return 4;
            default: return 2;
        }
    }

    /**
     * 获取房户状态
     */
    private Integer getHouseholdStatus(String status) {
        if (status == null) return 0; // 默认空置
        switch (status) {
            case "空置": return 0;
            case "已售": return 1;
            case "已租": return 3;
            default: return 0;
        }
    }

    /**
     * 获取字符串值
     */
    private String getStringValue(Map<String, Object> data, String key) {
        if (data == null || StringUtils.isBlank(key)) {
            return null;
        }
        Object value = data.get(key);
        if (value == null) {
            return null;
        }
        String strValue = value.toString().trim();
        return StringUtils.isBlank(strValue) ? null : strValue;
    }

    /**
     * 获取整数值
     */
    private Integer getIntegerValue(Map<String, Object> data, String key) {
        if (data == null || StringUtils.isBlank(key)) {
            return null;
        }
        Object value = data.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            String strValue = value.toString().trim();
            if (StringUtils.isBlank(strValue)) {
                return null;
            }
            return Integer.parseInt(strValue);
        } catch (NumberFormatException e) {
            log.warn("无法解析整数值，键：{}，值：{}", key, value);
            return null;
        }
    }

    /**
     * 获取BigDecimal值
     */
    private BigDecimal getBigDecimalValue(Map<String, Object> data, String key) {
        if (data == null || StringUtils.isBlank(key)) {
            return null;
        }
        Object value = data.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Number) {
            return new BigDecimal(value.toString());
        }
        try {
            String strValue = value.toString().trim();
            if (StringUtils.isBlank(strValue)) {
                return null;
            }
            return new BigDecimal(strValue);
        } catch (NumberFormatException e) {
            log.warn("无法解析BigDecimal值，键：{}，值：{}", key, value);
            return null;
        }
    }
}
